﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
using DynamicData;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Core;
using SimpleTool.ActivityUnit;
using SimpleTool.ActivityUnit.EchoControl;
using SimpleTool.Base;
using SimpleTool.Capacity;
using SimpleTool.SerialTool;
using SimpleTool.SerialTool.SerialControl;
using SimpleTool.TransformComponent;
using static ICSharpCode.SharpZipLib.Zip.ExtendedUnixData;
using static Microsoft.IO.RecyclableMemoryStreamManager;
using static SimpleTool.SerialTool.SerialControl.CommandSectionModel;

namespace SimpleTool.Server
{

    /// <summary>
    /// Params: 1. Path ; 2.Name ; 3.Password ; 4.EncryptValue ; 5.EncryptKey ; 6.Way
    /// </summary>
    public struct SqliteConnectionConfig
    {
        public string Path;

        public string Name;

        public string Password;

        public DatabaseConnectWay Way;
    }

    public sealed class SqliteExceuteResult
    {
        public Dictionary<string, Dictionary<string, ICollection<object>>> Result = [];

        public string? ErrorHint = null;

        public long? ScalarNumber = null;

        public long? ChangeRow = null;
    }

    public sealed class MvvmMessage(MvvmMessage.MvvmType type, object? msgBody = null, bool isResponse = false)
    {
        public enum MvvmType
        {
            Command_EditInfoSend,
            Command_EditInfoGet,
            Database_MapInfoGroup_Request,
            Database_MapInfoGroup_Acquire,
            Database_MapFilesSend,
            Mes_Acquire,
            SerialPort_ChildPage
        }

        public MvvmType Type = type;

        public object? MsgBody = msgBody;

        public bool IsResponse = isResponse;
    }

    public sealed class HyperlinkBack
    {
        public HyperlinkBackType LinkType = HyperlinkBackType.Invalid;

        public object? BindingData = null;
    }

    public sealed class ConnectFlag { public bool IsConnected = false; }

    public sealed class ExcelOptions(IEnumerable<string> files)
    {
        public List<string> Exc_Files = [.. files];

        public List<string> Exc_Sheet = [];

        public int Exc_MaxReaderNum = -1;

        public bool Exc_IsQuerySheet = true;

        public bool Exc_VisiblePrograss = true;

        public Action<string, string, double>? Exc_HintCallBack;
    }

    public sealed class ActivityDetetorSuccess
    {
        public string TestSteps = string.Empty;

        public string IMEI = string.Empty;
    }

    public sealed class DB
    {
        public readonly static List<string> LocalDBcryptKey = ["ZhongYiWuLianWang", "ZhiNeng"];

        public enum DB_TYPE
        {
            DB_Cloud,
            DB_Local,
            DB_Null
        }

        public enum DB_MAPKEY
        {
            LocalDataCache,
            CloudDataCache
        }

        public static string G_MapKeyName(DB_MAPKEY Keyenum)
        {
            string db_map_key = Keyenum switch
            {
                DB_MAPKEY.LocalDataCache => "SqliteStorage",
                DB_MAPKEY.CloudDataCache => "CloudeStorage",
                _ => "SqliteStorage",
            };
            return db_map_key;
        }

        public sealed class DBSurvivalCallBack(DB.DB_TYPE _type, TaskCompletionSource? _token = null)
        {
            public DB_TYPE DBTYPE = _type;
            public TaskCompletionSource? Token = _token;
        }
    }

    public sealed class LocalConfig
    {
        public sealed class Path
        {
            public readonly string AppDir = "Mydir".CurrentDir();
            public readonly string Log_DirName = "RuntimeRecord";
            public readonly string RTLog_DirTreeName = "RTLog";
            public readonly string RTLog_Mflag = "snapshot_";
            public readonly string RTLog_Datefm = "yyyy-MM-dd";
            public readonly string RTLog_Dir = string.Empty;

            public enum FileType
            {
                Mes,
                MesMap,
                Nor,
                Stalker,
                RTLog,
                RTLogDir,
                DVLog,
                TSTLog
            }

            public readonly static Path Object = new();

            private Path()
            {
                RTLog_Dir = System.IO.Path.Combine("MyLog".CurrentDir(), Log_DirName, RTLog_DirTreeName);
            }

            public static string? CreateDir(string dir)
            {
                if (Directory.Exists(dir)) return dir;
                List<string> splitPath = [.. RegExp.RegExpSplitPath().Split(dir)];
                if (splitPath.Count > 0)
                {
                    string combination = string.Empty;
                    for (int digit = 1; digit <= splitPath.Count; digit++)
                    {
                        combination = string.Join("/", splitPath.GetRange(0, digit));
                        try
                        {
                            if (!Directory.Exists(combination)) Directory.CreateDirectory(combination);
                        }
                        catch
                        {
                            continue;
                        }
                    }
                    if (Directory.Exists(combination)) return combination;
                }
                return null;
            }

            public static string? CreateFile(string file)
            {
                if (File.Exists(file)) return file;
                List<string> splitPath = [.. RegExp.RegExpSplitPath().Split(file)];
                string dir = string.Join("/", splitPath.GetRange(0, splitPath.Count - 1));
                file = string.Join("/", splitPath.GetRange(0, splitPath.Count));
                if (CreateDir(dir) is not null)
                {
                    try
                    {
                        using FileStream _File = File.Create(file);

                        if (File.Exists(file))
                        {
                            return file;
                        }
                    }
                    catch
                    {
                        return null;
                    }
                }
                return null;
            }

            public string G_Path(FileType type, string? name = null, string suffix = "ini")
            {
                string defaultPath = type switch
                {
                    FileType.Mes => System.IO.Path.Combine(AppDir, "Setting", "Mes", $"{name ?? "info"}.{suffix}"),
                    FileType.MesMap => System.IO.Path.Combine(AppDir, "Setting", "Mes", $"{name ?? "relation"}.{suffix}"),
                    FileType.Nor => System.IO.Path.Combine(AppDir, "Setting", "Self", $"{name ?? "setting"}.{suffix}"),
                    FileType.Stalker => System.IO.Path.Combine(AppDir, "Setting", "Stalker", $"{name ?? "Staler"}.{suffix}"),
                    FileType.RTLog => System.IO.Path.Combine(RTLog_Dir, $"{RTLog_Mflag}{@DateTime.Now.ToString(RTLog_Datefm)}.{suffix}"),
                    FileType.RTLogDir => RTLog_Dir,
                    FileType.DVLog => System.IO.Path.Combine(AppDir, Log_DirName, "DVL", $"DVL_{DateTime.Now:yyy_MM_dd_HH_mm_ss}.{suffix}"),
                    FileType.TSTLog => System.IO.Path.Combine(AppDir, Log_DirName, "TSTL", $"TSTL_{DateTime.Now:yyy_MM_dd_HH_mm_ss}.{suffix}"),
                    _ => System.IO.Path.Combine("MyDir".CurrentDir(), "Setting", "Self", $"{name ?? "setting"}.{suffix}")
                };
                if (CreateFile(defaultPath) is not null and string _path)
                {
                    return _path;
                }
                return string.Empty;
            }
        }

        public sealed class OwnerKey
        {
            public static readonly string DB = "DB";

            public static readonly string BS = "BS";

            public static readonly string Log = "LOG";
        }

        public enum DBCacheTreeKey
        {
            IsCloud
        }

        public enum RuntimeLogKey
        {
            OpeningLogTextBox
        }

        public enum BSCacheTreeKey
        {
            ExpectProduct,
            FuncIconStyle,
        }
    }

    public sealed class OrderFilterCondition
    {
        public enum FieldType
        {
            IMEI,
            SN,
            BLUE,
            ORDER,
            DOID,
            RLTALL
        }

        public sealed class Condition
        {
            public string FilterContent = string.Empty;

            public FieldType FilterFieldType = FieldType.IMEI;
        }

        public List<Condition> FilterConditions = [];

        public (long, long)? FilterRange = null;

        public bool Filter_isSimpleQuery = true;
    }

    /// <summary>
    /// Mode [Exact、Vague]
    /// <para>Filter_Path、Filter_Keyworks、Filter_Extensions、Filter_RealTimeData</para>
    /// </summary>
    /// <exception cref="NotImplementedException"></exception>
    public sealed class LocalFileFilterOptions
    {
        public enum Mode
        {
            Exact,
            Vague
        }

        public List<string> Filter_Paths = [];
        public List<string> Filter_Keyworks = [];
        public List<string> Filter_Extensions = [];
        public Mode Filter_Mode = Mode.Exact;
        public IProgress<(string, CancellationTokenSource)>? Progress = null;

        public LocalFileFilterOptions(List<string> filter_Path, List<string> filter_Keyworks, List<string> filter_Extensions, Action<(string, CancellationTokenSource)>? filter_RealTimeData, Mode mode)
        {
            Filter_Paths = filter_Path;
            Filter_Keyworks = filter_Keyworks;
            Filter_Extensions = filter_Extensions;
            if (filter_RealTimeData is not null) Progress = new Progress<(string, CancellationTokenSource)>(filter_RealTimeData);
            Filter_Mode = mode;
        }

        public LocalFileFilterOptions(string filter_Path, List<string> filter_Keyworks, List<string> filter_Extensions, Action<(string, CancellationTokenSource)>? filter_RealTimeData, Mode mode)
        {
            Filter_Paths = [filter_Path];
            Filter_Keyworks = filter_Keyworks;
            Filter_Extensions = filter_Extensions;
            if (filter_RealTimeData is not null) Progress = new Progress<(string, CancellationTokenSource)>(filter_RealTimeData);
            Filter_Mode = mode;
        }

        public LocalFileFilterOptions(string filter_Path, string filter_Keyworks, string filter_Extensions, Action<(string, CancellationTokenSource)>? filter_RealTimeData, Mode mode)
        {
            Filter_Paths = [filter_Path];
            Filter_Keyworks = [filter_Keyworks];
            Filter_Extensions = [filter_Extensions];
            if (filter_RealTimeData is not null) Progress = new Progress<(string, CancellationTokenSource)>(filter_RealTimeData);
            Filter_Mode = mode;
        }

        public LocalFileFilterOptions(List<string> filter_Path, string filter_Keyworks, string filter_Extensions, Action<(string, CancellationTokenSource)>? filter_RealTimeData, Mode mode)
        {
            Filter_Paths = filter_Path;
            Filter_Keyworks = [filter_Keyworks];
            Filter_Extensions = [filter_Extensions];
            if (filter_RealTimeData is not null) Progress = new Progress<(string, CancellationTokenSource)>(filter_RealTimeData);
            Filter_Mode = mode;
        }
    }

    public struct KvpGroup
    {
        public KvpGroup()
        {
            Cancel = true;

            SHowyDatas = [];
        }

        public class Sec
        {
            public string Content { set; get; } = string.Empty;

            public string WidgetType { set; get; } = string.Empty;

            public string Flag { set; get; } = string.Empty;

            public ICollection<string> Selects { set; get; } = [];
        }

        public bool Cancel { set; get; }

        public ICollection<Sec> SHowyDatas { set; get; }
    }

    public sealed class UIBind(Interfacial uIType)
    {
        public static readonly Dictionary<Interfacial, Type> FactoryMap = new()
        {
                {  Interfacial.SRLPSerialPort, typeof(OverViewUI) },
                {  Interfacial.SRLPConfig, typeof(SerialConfigUI) },
                {  Interfacial.SRLPCommand, typeof(SerialCommandUI) },
                {  Interfacial.CPCTCapacity, typeof(CapacityUI) },
                {  Interfacial.PRDTActivity, typeof(ActivityUI) },
                {  Interfacial.PRDTAttributeConfig, typeof(ProductConfigUI) },
                {  Interfacial.PRDTProductOutTextBox, typeof(ProductRichBoxUI) },
                {  Interfacial.PRDTProductRegister, typeof(ProductRegisterUI) },
                {  Interfacial.PRDTDBmapUI, typeof(ReserveDutyMapUI) },
                {  Interfacial.PRDTProductPreView, typeof(ProductPreviewUI) },
        };

        public Interfacial UIType { set; get; } = uIType;

        public bool IsPlayAnimation { set; get; } = false;

        public Action? InstantiationCallBack { set; get; } = null;
    }

    public sealed class Deserted : Notify
    {
        private bool _CapCTRichBox = false;

        private bool _CapCTAttributeConfig = false;

        private bool _CapCTDBfieldConfig = false;

        private bool _DoCtClearRichBox = false;

        private bool _DoImeiFocusTextBox = false;

        public object? _IFLoadMesMapInfoPush = null;

        private object? _IFLoadDBMapInfoPush = null;

        public string? _IFLoadAttrStepAddPush = null;

        public List<TestItemDeepSeatedSealed>? _IFLoadAttrItemsAddPush = null;

        public bool CapCTRichBox
        {
            set
            {
                _CapCTRichBox = value;
                propertyChangeSend(nameof(CapCTRichBox));
            }
            get
            {
                return _CapCTRichBox;
            }
        }

        public bool CapCTAttributeConfig
        {
            set
            {
                _CapCTAttributeConfig = value;
                propertyChangeSend(nameof(CapCTAttributeConfig));
            }
            get
            {
                return _CapCTAttributeConfig;
            }
        }

        public bool CapCTDBfieldConfig
        {
            set
            {
                _CapCTDBfieldConfig = value;
                propertyChangeSend(nameof(CapCTDBfieldConfig));
            }
            get
            {
                return _CapCTDBfieldConfig;
            }
        }

        public bool DoCtClearRichBox
        {
            set
            {
                _DoCtClearRichBox = value;
                propertyChangeSend(nameof(DoCtClearRichBox));
            }
            get
            {
                return _DoCtClearRichBox;
            }
        }

        public bool DoImeiFocusTextBox
        {
            set
            {
                _DoImeiFocusTextBox = value;
                propertyChangeSend(nameof(DoImeiFocusTextBox));
            }
            get
            {
                return _DoImeiFocusTextBox;
            }
        }

        public object? IFLoadMesMapInfoPush
        {
            set
            {
                _IFLoadMesMapInfoPush = value;
                propertyChangeSend(nameof(IFLoadMesMapInfoPush));
            }
            get
            {
                return _IFLoadMesMapInfoPush;
            }
        }

        public object? IFLoadDBMapInfoPush
        {
            set
            {
                _IFLoadDBMapInfoPush = value;
                propertyChangeSend(nameof(IFLoadDBMapInfoPush));
            }
            get
            {
                return _IFLoadDBMapInfoPush;
            }
        }

        public string? IFLoadAttrStepAddPush
        {
            set
            {
                _IFLoadAttrStepAddPush = value;
                propertyChangeSend(nameof(IFLoadAttrStepAddPush));
            }
            get
            {
                return _IFLoadAttrStepAddPush;
            }
        }

        public List<TestItemDeepSeatedSealed>? IFLoadAttrItemsAddPush
        {
            set
            {
                _IFLoadAttrItemsAddPush = value;
                propertyChangeSend(nameof(IFLoadAttrItemsAddPush));
            }
            get
            {
                return _IFLoadAttrItemsAddPush;
            }
        }
    }

    public sealed class Argument : Notify
    {
        private readonly ILogger Logger = Log.ForContext<Argument>();
        private readonly IActivityDetetorServer ActivityDetetorServer;
        private readonly IDataBaseServer DataBaseServer;
        private string _order = string.Empty;
        private string _sn = string.Empty;
        private string _imei = string.Empty;
        private string _blue = string.Empty;
        private string _doid = string.Empty;
        private string _qrcode1 = string.Empty;
        private string _qrcode2 = string.Empty;
        private int _index = -1;

        private ICommand? SnChangedStdin;

        private ICommand? ImeiChangedStdin;

        private ICommand? SearchStdin;

        private ICommand? ClearningStdin;

        public Argument()
        {
            App MyApp = (App)Application.Current;
            ActivityDetetorServer = MyApp.ServiceProvider.GetRequiredService<IActivityDetetorServer>();
            DataBaseServer = MyApp.ServiceProvider.GetRequiredService<IDataBaseServer>();
        }

        public string Order
        {
            get => _order;
            set
            {
                if (_order != value)
                {
                    _order = value ?? string.Empty;
                    propertyChangeSend(nameof(Order));
                    Log.Logger?.Information("Order set to: {OrderValue}", _order);
                }
            }
        }

        public string Sn
        {
            get => _sn;
            set
            {
                if (_sn != value)
                {
                    _sn = value ?? string.Empty;
                    propertyChangeSend(nameof(Sn));
                }
            }
        }

        public string Imei
        {
            get => _imei;
            set
            {
                if (_imei != value)
                {
                    _imei = value ?? string.Empty;
                    propertyChangeSend(nameof(Imei));
                }
            }
        }

        public string Blue
        {
            get => _blue;
            set
            {
                if (_blue != value)
                {
                    _blue = value ?? string.Empty;
                    propertyChangeSend(nameof(Blue));
                }
            }
        }

        public string Doid
        {
            get => _doid;
            set
            {
                if (_doid != value)
                {
                    _doid = value ?? string.Empty;
                    propertyChangeSend(nameof(Doid));
                }
            }
        }

        public string Qrcode1
        {
            get => _qrcode1;
            set
            {
                if (_qrcode1 != value)
                {
                    _qrcode1 = value ?? string.Empty;
                    propertyChangeSend(nameof(Qrcode1));
                }
            }
        }

        public string Qrcode2
        {
            get => _qrcode2;
            set
            {
                if (_qrcode2 != value)
                {
                    _qrcode2 = value ?? string.Empty;
                    propertyChangeSend(nameof(Qrcode2));
                }
            }
        }

        public int SelectIndex
        {
            set
            {
                _index = value;
                SelectionChange(_index);
                propertyChangeSend(nameof(SelectIndex));
            }
            get
            {
                return _index;
            }
        }

        public ICommand CmdClearning
        {
            set
            {
                ClearningStdin = value;
            }
            get
            {
                ClearningStdin ??= new EasyCommand(Clearning, () => true);
                return ClearningStdin;
            }
        }

        public ICommand CmdSearch
        {
            set
            {
                SearchStdin = value;
            }
            get
            {
                SearchStdin ??= new EasyCommand(Search, () => true);
                return SearchStdin;
            }
        }

        public ICommand CmdSnChanged
        {
            set
            {
                SnChangedStdin = value;
            }
            get
            {
                SnChangedStdin ??= new EasyCommand(SnChangedEvent, () => true);
                return SnChangedStdin;
            }
        }

        public ICommand CmdImeiChanged
        {
            set
            {
                ImeiChangedStdin = value;
            }
            get
            {
                ImeiChangedStdin ??= new EasyCommand(ImeiChangedEvent, () => true);
                return ImeiChangedStdin;
            }
        }

        public ObservableCollection<string>? SourceItemsStdin = [];

        public ObservableCollection<string>? SourceItems
        {
            set
            {
                SourceItemsStdin = value;
                propertyChangeSend(nameof(SourceItems));
            }
            get
            {
                return SourceItemsStdin;
            } 
        }

        private readonly Dictionary<string, ICollection<string>> SearchMatchMap = [];

        private void Search(object? param)
        {
            if (param is not null and string _flag)
            {
                (string, OrderFilterCondition.FieldType) INFO = _flag switch
                {
                    nameof(OrderFilterCondition.FieldType.IMEI) => (Imei, OrderFilterCondition.FieldType.IMEI),
                    nameof(OrderFilterCondition.FieldType.DOID) => (Doid, OrderFilterCondition.FieldType.DOID),
                    nameof(OrderFilterCondition.FieldType.SN) => (Sn, OrderFilterCondition.FieldType.SN),
                    nameof(OrderFilterCondition.FieldType.BLUE) => (Blue, OrderFilterCondition.FieldType.BLUE),
                    nameof(OrderFilterCondition.FieldType.ORDER) => (Order, OrderFilterCondition.FieldType.ORDER),
                    _ => (Imei, OrderFilterCondition.FieldType.IMEI)
                };
                MatchDeviceInfos(INFO.Item1, INFO.Item2);
            }
        }

        private void SnChangedEvent(object? param)
        {
            if (param is not null and string _content && _content.Length > 20)
            {
                try
                {
                    Dictionary<int, string> matchAll = _content.MatchAll("[0-9a-zA-Z]{15,20}");
                    
                    foreach (var kvp in matchAll)
                    {
                        Logger.Print(RuntimeLog.LogType.Info, "sn change info: ", kvp.Key, kvp.Value);

                        MatchDeviceInfos(kvp.Value, OrderFilterCondition.FieldType.SN);
                    }
                } 
                catch (Exception error)
                {
                    Logger.Print(RuntimeLog.LogType.Error, error.Message);
                }

            }
        }

        private void ImeiChangedEvent(object? param)
        {
            if (param is not null and string _content && _content.Length > 15)
            {
                try
                {
                    Dictionary<int, string> matchAll = _content.MatchAll("[0-9a-zA-Z]{15,20}");

                    foreach (var kvp in matchAll)
                    {
                        Logger.Print(RuntimeLog.LogType.Info, "imei change info: ", kvp.Key, kvp.Value);

                        MatchDeviceInfos(kvp.Value, OrderFilterCondition.FieldType.IMEI);
                    }
                }
                catch (Exception error)
                {
                    Logger.Print(RuntimeLog.LogType.Error, "ImeiChangedEvent:", error.Message);
                }
            }
        }

        private void MatchDeviceInfos(string content = "", OrderFilterCondition.FieldType FieldType = OrderFilterCondition.FieldType.IMEI)
        {
            Application.Current.Dispatcher.Invoke(async () =>
            {
                if ((FieldType == OrderFilterCondition.FieldType.IMEI && content.Length > 15) ||
                    (FieldType == OrderFilterCondition.FieldType.SN && content.Length > 20))
                {
                    (bool, Dictionary<string, string>) match = await GetValidNumber(content);

                    if (match.Item1)
                    {
                        if (FieldType == OrderFilterCondition.FieldType.SN && match.Item2.TryGetValue(nameof(OrderFilterCondition.FieldType.SN), out string? _SN))
                        {
                            content = _SN;
                            FieldType = OrderFilterCondition.FieldType.SN;
                        }
                        else if (FieldType == OrderFilterCondition.FieldType.IMEI && match.Item2.TryGetValue(nameof(OrderFilterCondition.FieldType.IMEI), out string? _IMEI))
                        {
                            content = _IMEI;
                            FieldType = OrderFilterCondition.FieldType.IMEI;
                        }
                    }
                }

                List<OrderFilterCondition.Condition> Conditions = [ new OrderFilterCondition.Condition()
                {
                    FilterContent = content,
                    FilterFieldType = FieldType
                }];

                if (Order.IsAbsoluteValidValue())
                {
                    Conditions.Add(new OrderFilterCondition.Condition
                    {
                        FilterContent = Order,
                        FilterFieldType = OrderFilterCondition.FieldType.ORDER
                    });
                }
                else
                {
                    IEnumerable<OrderFilterCondition.Condition> OrderItems = Conditions.Where(x => x.FilterFieldType == OrderFilterCondition.FieldType.ORDER);

                    foreach (var i in OrderItems) Conditions.Remove(i);
                }

                object? result = await ActivityDetetorServer.AutoFindDim(new OrderFilterCondition()
                {
                    FilterConditions = Conditions,
                });

                if (result is not null and Supabase.Postgrest.Responses.ModeledResponse<WorkOrderUnfold> UnfoldResponse &&
                    UnfoldResponse.Models.Count > 0)
                {
                    if (UnfoldResponse.Models.Count > 0)
                    {
                        List<string> ORDERS = [.. UnfoldResponse.Models.Select(x => x.WorkorderNum)];
                        List<string> IMEIS = [.. UnfoldResponse.Models.Select(x => x.Imei)]; ;
                        List<string> SNS = [.. UnfoldResponse.Models.Select(x => x.Sn)];
                        List<string> BLUES = [.. UnfoldResponse.Models.Select(x => x.BlueMac)];
                        List<string> DOIDS = [.. UnfoldResponse.Models.Select(x => x.Id)];

                        ObservableCollection<string> ItemsSources = [];

                        switch (FieldType)
                        {
                            case OrderFilterCondition.FieldType.IMEI:
                                ItemsSources = OrderItems<string>(IMEIS);
                                break;
                            case OrderFilterCondition.FieldType.SN:
                                ItemsSources = OrderItems(SNS);
                                break;
                            case OrderFilterCondition.FieldType.BLUE:
                                ItemsSources = OrderItems(BLUES);
                                break;
                            case OrderFilterCondition.FieldType.DOID:
                                ItemsSources = OrderItems(DOIDS);
                                break;
                        }

                        SearchMatchMap[nameof(Order)] = ORDERS;
                        SearchMatchMap[nameof(Imei)] = IMEIS;
                        SearchMatchMap[nameof(Sn)] = SNS;
                        SearchMatchMap[nameof(Blue)] = BLUES;
                        SearchMatchMap[nameof(Doid)] = DOIDS;

                        //SourceItems = [];

                        SourceItems = ItemsSources;

                        if (SourceItems?.Count == 1) SelectionChange(0);
                    }
                    else
                    {
                        SourceItems?.Clear();
                    }
                }

                else
                {
                    if (result is not null and Dictionary<string, ICollection<object>> TableDataMap)
                    {
                        ObservableCollection<string> ExpectDatas = [];

                        if (TableDataMap.TryGetValue("sn", out ICollection<object>? _SNS) &&
                            TableDataMap.TryGetValue("workorder_num", out ICollection<object>? _ORDERS) &&
                            TableDataMap.TryGetValue("imei", out ICollection<object>? _IMEIS) &&
                            TableDataMap.TryGetValue("blue_mac", out ICollection<object>? _MACS) &&
                            TableDataMap.TryGetValue("id", out ICollection<object>? _IDS))
                        {
                            List<string> ORDERS = [.. _ORDERS.Select(x => x.GetSafetyChar())];
                            List<string> IMEIS = [.. _IMEIS.Select(x => x.GetSafetyChar())];
                            List<string> SNS = [.. _SNS.Select(x => x.GetSafetyChar())];
                            List<string> BLUES = [.. _MACS.Select(x => x.GetSafetyChar())];
                            List<string> DOIDS = [.. _IDS.Select(x => x.GetSafetyChar())];

                            SearchMatchMap[nameof(Order)] = ORDERS;
                            SearchMatchMap[nameof(Imei)] = IMEIS;
                            SearchMatchMap[nameof(Sn)] = SNS;
                            SearchMatchMap[nameof(Blue)] = BLUES;
                            SearchMatchMap[nameof(Doid)] = DOIDS;

                            switch (FieldType)
                            {
                                case OrderFilterCondition.FieldType.IMEI:
                                    ExpectDatas = OrderItems(IMEIS);
                                    break;
                                case OrderFilterCondition.FieldType.SN:
                                    ExpectDatas = OrderItems(SNS);
                                    break;
                                case OrderFilterCondition.FieldType.BLUE:
                                    ExpectDatas = OrderItems(BLUES);
                                    break;
                                case OrderFilterCondition.FieldType.DOID:
                                    ExpectDatas = OrderItems(DOIDS);
                                    break;
                            }
                        }

                        //SourceItems = [];

                        SourceItems = ExpectDatas;

                        if (SourceItems?.Count == 1) SelectionChange(0);
                    }
                    else
                    {
                        SourceItems?.Clear();
                    }
                }
            });
        }
        
        public async Task<(bool, Dictionary<string, string>)> GetValidNumber(string content)
        {
            Dictionary<int, string> matchAll = content.MatchAll("[0-9a-zA-Z]{15,20}");

            if (DataBaseServer.GetDBIdentify() == DB.DB_TYPE.DB_Cloud)
            {
                if (DataBaseServer.GetCloudDB() is not null and Supabase.Client CloudDB)
                {
                    foreach (var number in matchAll.Values)
                    {
                        var queryResult = await CloudDB.From<WorkOrderUnfold>()
                            .Select(x => new object[] { x.Sn, x.Imei })
                            .Where(x => x.Imei == number || x.Sn == number)
                            .Get();

                        if (queryResult.Model is not null && queryResult.Models.Count == 1)
                        {
                            return (true, new Dictionary<string, string>() { { "SN", queryResult.Model.Sn }, { "IMEI", queryResult.Model.Imei } });
                        }
                    }
                }
            }
            else if (DataBaseServer.GetDBIdentify() == DB.DB_TYPE.DB_Local)
            {
                foreach (var number in matchAll.Values)
                {
                    string queryCommandSql = $"SELECT sn,imei FROM workorder_unfold WHERE imei='{number}' or sn='{number}'";

                    if (await DataBaseServer.LocalDBQueryFree(queryCommandSql) is not null and SqliteExceuteResult _queryResult &&
                        _queryResult.ErrorHint is null &&
                        _queryResult.Result.TryGetValue(queryCommandSql, out Dictionary<string, ICollection<object>>? _resultMap))
                    {
                        if (_resultMap.TryGetValue("sn", out ICollection<object>? SNS) && 
                            _resultMap.TryGetValue("imei", out ICollection<object>? IMEIS) &&
                            SNS.Count >= 1 && IMEIS.Count >= 1)
                        {
                            if (SNS.Reteller(0) is not null and string _Snvalue &&
                                IMEIS.Reteller(0) is not null and string _Imeivalue)
                            {
                                return (true, new Dictionary<string, string>() { { "SN", _Snvalue }, { "IMEI", _Imeivalue } });
                            }
                        }
                    }
                }
            }
            return (false, []);
        }

        private void SelectionChange(int index)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                foreach (var i in SearchMatchMap)
                {
                    if (i.Key == nameof(Order))
                    {
                        Order = i.Value.Reteller(index) ?? Order;
                    }
                    else if (i.Key == nameof(Imei))
                    {
                        Imei = i.Value.Reteller(index) ?? Imei;
                    }
                    else if (i.Key == nameof(Sn))
                    {
                        Sn = i.Value.Reteller(index) ?? Sn;
                    }
                    else if (i.Key == nameof(Blue))
                    {
                        Blue = i.Value.Reteller(index) ?? Blue;
                    }
                    else if (i.Key == nameof(Doid))
                    {
                        Doid = i.Value.Reteller(index) ?? Doid;
                    }
                }
            });
        }

        private static ObservableCollection<string> OrderItems<T>(ICollection<T> SourceIter)
        {
            ObservableCollection<string> results = [];
            for(int index = 0; index < SourceIter.Count; index++)
            {
                results.Add($"{index + 1}. {SourceIter.ElementAt(index)}");
            }
            return results;
        }

        public void Clearning(object? param)
        {
            SelectIndex = -1;
            Imei = string.Empty;
            Sn = string.Empty;
            Blue = string.Empty;
            Doid = string.Empty;
        }
    }
}
